package com.sky.aspect;

import cn.hutool.core.date.DateTime;
import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.entity.Employee;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @BelongsProject: sky-take-out
 * @BelongsPackage: com.sky.aspect
 * @Author: XieMingHui
 * @CreateTime: 2023-11-17  15:52
 * @Description: TODO
 * @Version: 1.0
 */
@Aspect //声明切面类
@Component // IOC
@Slf4j
public class AutoFillAspect {
    // 前置通知,修改方法的参数
    @Before("@annotation(com.sky.annotation.AutoFill)")
    public void autoFill(JoinPoint point) {
        // 1先判断注解的属性值,确定不同的切面编程
        //1.1 获取强转为MethodSignature
        MethodSignature method = (MethodSignature) point.getSignature();
        //1.2 获取注解
        AutoFill annotation = method.getMethod().getAnnotation(AutoFill.class);
        //1.3 获取注解值
        OperationType value = annotation.value();
        // 获取方法参数对象
        Object object = point.getArgs()[0];
        // 获取参数对象的Class对象,用于后面反射获取set方法赋值
        Class<?> aClass =object.getClass();
        // 创建的相关字段的值
        Long id = BaseContext.getCurrentId().getId();
        LocalDateTime localDateTime = DateTime.now().toLocalDateTime();
        // 根据注解的值执行不同的逻辑
        if (value == OperationType.INSERT) {
            // 新增操作
            //为4个公共字段赋值
            try {
                // 获取所有权限下的对应名称的成员方法对象
                Method setCreateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setCreateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //通过反射方法invoke为成员方法对象属性赋值
                setCreateTime.invoke(object, localDateTime);
                setCreateUser.invoke(object, id);
                setUpdateTime.invoke(object, localDateTime);
                setUpdateUser.invoke(object, id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (value == OperationType.UPDATE) {
            // 更新操作
            //为2个公共字段赋值
            try {
                Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //通过反射为对象属性赋值
                setUpdateTime.invoke(object, localDateTime);
                setUpdateUser.invoke(object, id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
